<template>
  <div class="game-container">
    <div ref="canvasContainer" class="canvas-container"></div>
    <div class="controls">
      <button @click="drawBall" :disabled="isDrawing || balls.length === 0">
        {{ isDrawing ? '抽奖中...' : '开始抽奖' }}
      </button>
      <div v-if="drawnBalls.length > 0" class="drawn-balls">
        <h3>已抽中:</h3>
        <div class="balls-grid">
          <div v-for="ball in drawnBalls" :key="ball.number" class="drawn-ball">
            {{ ball.number }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import * as PIXI from 'pixi.js'
import { Engine, World, Bodies, Events } from 'matter-js'

// 类型定义
interface Ball {
  body: Matter.Body
  number: number
  graphics: PIXI.Graphics
  sprite: PIXI.Sprite
}

interface DrawnBall {
  number: number
  position: { x: number; y: number }
}

// 响应式数据
const canvasContainer = ref<HTMLElement | null>(null)
const isDrawing = ref(false)
const drawnBalls = ref<DrawnBall[]>([])
const balls = ref<Ball[]>([])

// Matter.js 和 Pixi.js 实例
let engine: Matter.Engine
let app: PIXI.Application
let world: Matter.World
let ground: Matter.Body | null = null
let walls: Matter.Body[] = []

// 粒子系统

// 初始化游戏
onMounted(async () => {
  if (!canvasContainer.value) return

  // 初始化 Pixi.js 渲染
  await initPixi()

  // 初始化 Matter.js 物理引擎
  await initMatter()

  // 创建奖池和球
  createPool()
  createBalls()

  // 开始物理模拟
  runEngine()
})

// 清理资源
onBeforeUnmount(() => {
  if (app) {
    app.destroy(true)
  }
  if (engine) {
    Engine.clear(engine)
  }
})

// 初始化 Pixi.js
const initPixi = async () => {
  if (!canvasContainer.value) return

  // 创建 PixiJS 应用
  app = new PIXI.Application()

  await app.init({
    width: 400,
    height: 600,
    backgroundColor: 0x1099bb,
    antialias: true,
    sharedTicker: true,
  })
  canvasContainer.value.appendChild(app.canvas as HTMLCanvasElement)

  // 添加背景
  const background = new PIXI.Graphics()
  background.rect(0, 0, 400, 600)
  background.fill(0x1a1a2e)
  app.stage.addChild(background)

  // 添加标题
  const title = new PIXI.Text('双色球抽奖', {
    fontFamily: 'Arial',
    fontSize: 36,
    fontWeight: 'bold',
    fill: 0xffffff,
    align: 'center',
  })
  title.anchor.set(0.5)
  title.x = 100
  title.y = 30
  app.stage.addChild(title)
}

// 初始化 Matter.js
const initMatter = () => {
  engine = Engine.create({
    enableSleeping: false,
    gravity: { x: 0, y: 1 },
  })
  world = engine.world

  // 创建地面和墙壁
  const groundWidth = 400
  const groundHeight = 400

  ground = Bodies.rectangle(groundWidth / 2, groundHeight + 50, groundWidth, 100, {
    isStatic: true,
    friction: 0.1,
    frictionAir: 0.001,
    restitution: 0.5,
    render: { visible: false },
  })

  walls = [
    Bodies.rectangle(-50, groundHeight / 2, 100, groundHeight * 2, {
      isStatic: true,
      render: { visible: false },
    }),
    Bodies.rectangle(groundWidth + 50, groundHeight / 2, 100, groundHeight * 2, {
      isStatic: true,
      render: { visible: false },
    }),
    Bodies.rectangle(groundWidth / 2, -50, groundWidth, 100, {
      isStatic: true,
      render: { visible: false },
    }),
  ]

  World.add(world, [ground, ...walls])

  // 添加边界约束
  Events.on(engine, 'afterUpdate', () => {
    // 创建临时副本避免遍历时修改数组
    const activeBalls = [...balls.value]
    activeBalls.forEach((ball) => {
      const pos = ball.body.position
      // 精确边界计算（增加缓冲值）
      const minX = 50,
        maxX = 360 // 奖池x:10-390，留5px缓冲
      const minY = 130,
        maxY = 370 // 奖池y:100-400，留5px缓冲

      pos.x = Math.min(Math.max(pos.x, minX), maxX)
      pos.y = Math.min(Math.max(pos.y, minY), maxY)
    })
  })
}

// 创建奖池
const createPool = () => {
  const pool = new PIXI.Graphics()
  pool.beginFill(0x164a6a, 0.3) // 增强奖池可见性
  pool.lineStyle(6, 0xff0000, 1) // 加粗边框
  pool.drawRoundedRect(10, 100, 380, 300, 25) // 调整圆角大小
  pool.endFill()
  app.stage.addChild(pool)
}

// 创建球
const createBalls = () => {
  const ballCount = 10
  const radius = 25 // 统一球体大小
  for (let i = 0; i < ballCount; i++) {
    // 固定半径值
    const x = 200 + Math.random() * 100 - radius // 缩小初始分布范围
    const y = 250 + Math.random() * 50 - radius

    // 创建物理体（保持原有参数）
    const body = Bodies.circle(x, y, radius, {
      restitution: 0.95,
      friction: 0.01,
      frictionAir: 0.005,
    })

    // 创建图形（双色渐变）
    const graphics = new PIXI.Graphics()
    graphics.lineStyle(2, i < 5 ? 0xcc0000 : 0x0000cc) // 红色球加红边，蓝色球加蓝边
    graphics.beginFill(i < 5 ? 0xff3366 : 0x3366ff)
    graphics.drawCircle(0, 0, radius)
    graphics.endFill()

    // 添加数字（优化显示）
    const text = new PIXI.Text((i + 1).toString(), {
      fontSize: 20, // 字号自适应半径
      fill: i < 5 ? 0xffcccc : 0xccccff, // 文字颜色适配球色
    })
    text.anchor.set(0.5)
    graphics.addChild(text)

    // 创建 Pixi.js 精灵
    const sprite = new PIXI.Sprite(app.renderer.generateTexture(graphics))
    sprite.anchor.set(0.5)
    sprite.x = x
    sprite.y = y
    app.stage.addChild(sprite)

    // 保存球数据
    balls.value.push({ body, number: i + 1, graphics, sprite })

    // 添加到物理世界
    World.add(world, body)
  }
}

// 运行物理引擎
const runEngine = () => {
  if (!engine) return

  const animate = () => {
    if (!engine || balls.value.length === 0) return // 添加终止条件

    Engine.update(engine, 16)

    // 更新球体位置和旋转
    balls.value.forEach((ball) => {
      const { position, velocity } = ball.body
      ball.sprite.x = position.x
      ball.sprite.y = position.y
      ball.sprite.rotation = Math.atan2(velocity.y, velocity.x) * 0.1

      // 添加随机力
      const force = 0.03
      ball.body.force.x += (Math.random() - 0.5) * force
      ball.body.force.y += (Math.random() - 0.5) * force
    })

    requestAnimationFrame(animate)
  }

  animate()
}

// 抽奖逻辑（修复球未移除问题）
const drawBall = async () => {
  if (isDrawing.value || balls.value.length === 0) return

  isDrawing.value = true
  const randomIndex = Math.floor(Math.random() * balls.value.length)
  const selectedBall = balls.value[randomIndex]

  // 立即移除物理体和精灵（关键修复）
  World.remove(world, selectedBall.body)
  app.stage.removeChild(selectedBall.sprite)

  // 强制清除物理引擎引用（新增）
  engine.world.bodies = engine.world.bodies.filter((b) => b !== selectedBall.body)

  balls.value.splice(randomIndex, 1) // 先移除数组引用
  console.log(`球 ${selectedBall.number} 已移除，剩余数量：${balls.value.length}`)
  // 更新已抽中列表（延迟添加保证数据同步）
  setTimeout(() => {
    drawnBalls.value.push({
      number: selectedBall.number,
      position: { x: selectedBall.sprite.x, y: selectedBall.sprite.y },
    })
    selectedBall.sprite.destroy({ children: true, texture: true }) // 彻底销毁
  }, 0)

  await new Promise((resolve) => setTimeout(resolve, 500))
  isDrawing.value = false
  console.log('app-->', app)

  // 遍历舞台上的所有子元素
  app.stage.children.forEach((child) => {
    // 筛选出精灵（Sprite 实例）
    if (child instanceof PIXI.Sprite) {
      const sprite = child as PIXI.Sprite

      // 输出精灵信息
      console.log('发现精灵:', {
        name: sprite.name || '未命名精灵',
        texture: sprite.texture.baseTexture.resource?.source?.src || '无纹理',
        position: { x: sprite.x, y: sprite.y },
        visible: sprite.visible,
      })
    }
  })
  // 强制立即重绘（新增）
  app.renderer.render(app.stage)

  // 延迟清理残留（保险措施）
  setTimeout(() => {
    app.renderer.render(app.stage)
  }, 100)
}
</script>

<style scoped>
.game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 500px;
  height: 100vh;
  background-color: #1a1a2e;
  color: white;
  font-family: Arial, sans-serif;
}

.canvas-container {
  width: 400px;
  height: 600px;
  margin-bottom: 20px;
  border: 2px solid #164a6a;
  border-radius: 10px;
  overflow: hidden;
}

.controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

button {
  padding: 12px 24px;
  font-size: 18px;
  font-weight: bold;
  color: white;
  background-color: #ff3366;
  border: none;
  border-radius: 50px;
  cursor: pointer;
  transition: all 0.3s ease;
}

button:hover:not(:disabled) {
  background-color: #ff6699;
  transform: scale(1.05);
}

button:disabled {
  background-color: #666666;
  cursor: not-allowed;
}

.drawn-balls {
  text-align: center;
}

.balls-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
  margin-top: 10px;
}

.drawn-ball {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: #ff3366;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: bold;
  color: white;
  margin: 0 auto;
}

.complete-message {
  text-align: center;
  padding: 20px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 10px;
}
</style>
